﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace EgoalTech.MTrade.Query
{
    class ExpressionConvert : ExpressionVisitor
    {
        private StringBuilder sb;
        private Expression expr;

        public ExpressionConvert(Expression expr)
        {
            this.expr = expr;
            this.sb = new StringBuilder();
        }

        public override Expression Visit(Expression node)
        {
            switch (node.NodeType)
            {
                case ExpressionType.MemberAccess:
                    return VisitMemberAccess((MemberExpression)node);
                case ExpressionType.Constant:
                    return VisitConstant((ConstantExpression)node);
                case ExpressionType.Negate:
                    sb.Append(node.ToString());
                    return node;
                default:
                    throw new NotImplementedException(node.NodeType.ToString());
            }
        }

        private Expression VisitNegate(UnaryExpression node)
        {
            return node;
        }

        protected override Expression VisitMemberAccess(MemberExpression node)
        {
            sb.Append(node.ToString());
            return base.VisitMemberAccess(node);
        }

        protected override Expression VisitConstant(ConstantExpression node)
        {
            if (node.Type == typeof(string))
            {
                sb.Append(string.Format("'{0}'", node.Value));
                return node;
            }

            if (node.Type == typeof(bool))
            {
                sb.Append((bool)node.Value ? 1 : 0);
                return node;
            }

            if (node.Type == typeof(DateTime))
            {
                sb.Append("'");
                sb.Append(((DateTime)node.Value).ToString("yyyy-MM-dd hh:mm:ss"));
                sb.Append("'");
                return node;
            }

            sb.Append(node.ToString());
            return node;
        }


        public string ToText()
        {
            Visit(expr);
            return sb.ToString();
        }
    }
}
